{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Deep Reinforcement Learning\n",
    "\n",
    "![mario](../images/mario.jpg)\n",
    "\n",
    "Reinforcement learning is one of the hottest (if not the hottest) area of deep learning. It is possibly the closest that we have come to achieving general AI at this point in time. The reason it is touted as getting close to general AI is that we can use the same framework repeatedly in different environments to maximise future rewards. Apart from the ATARI games in which [Deep Reinforcement Learning got famous](https://web.stanford.edu/class/psych209/Readings/MnihEtAlHassibis15NatureControlDeepRL.pdf) for and beating the current world GO chamption, it is now being used in finance and [teaching robots to walk](https://www.youtube.com/watch?v=JFJkpVWTQVM).\n",
    "\n",
    "The general concept of RL is to simulate game a large number of times and to learn which actions constitutes a good move. One of the biggest challenges that RL faces is to infer what constitutes a good move. A good move at the current state might be a bad move for future states. This is definitely the case in playing chess for example where you constantly sacrifice pieces for larger future rewards.\n",
    "\n",
    "## Belman Equation\n",
    "\n",
    "The goal of reinforcement learning is to maximise its return. In this tutorial we get 'envirnonments' from OpenAI which provides us a game, the physics/ rules by which the game is controlled by and outputs the **rewards** achieved for a given **action**, at the current **state** of the game.\n",
    "\n",
    "The bellman equation plays a crucial role in reinforcement learning.\n",
    "\\begin{align}\n",
    "Q(S_t)(a_t) = r_t + \\gamma\\max_{a_{t+1}}Q(S_{t+1})(a_{t+1})\n",
    "\\end{align}\n",
    "where $Q$ is a quality function, which depends on state $S_t$ and outputs the maximum possible future reward for action $a_t$. $\\gamma$ is a discount factor. Most texts would prefer to depict the Quality function as $Q(S_t, a_t)$, however I wish to stress that $Q(S_t)$ outputs the maximum discounted future reward for all actions. $a_t$ is in this tutorial, a one-hot encoded variable which helps to choose a reward for all possible actions. **Notice how could recursively expand this function.**\n",
    "\n",
    "## Pseudocode for DQN\n",
    "Reference: https://github.com/yenchenlin/DeepLearningFlappyBird\n",
    "```\n",
    "Initialize replay memory D to size N\n",
    "Initialize action-value function Q with random weights\n",
    "for episode = 1, M do\n",
    "    Initialize state s_1\n",
    "    for t = 1, T do\n",
    "        With probability ϵ select random action a_t\n",
    "        otherwise select a_t=max_a  Q(s_t,a)\n",
    "        Execute action a_t in emulator and observe r_t and s_(t+1) and if terminated\n",
    "        Store transition (s_t,a_t,r_t,s_(t+1)) in D\n",
    "        if episode > observation episodes:\n",
    "            Sample a minibatch of transitions (s_j,a_j,r_j,s_(j+1)) from D\n",
    "            Set y_j:=\n",
    "                r_j for terminal s_(j+1)\n",
    "                r_j+γ*max_(a^' )  Q(s_(j+1),a'; θ_i) for non-terminal s_(j+1)\n",
    "            Perform a gradient step on (y_j-Q(s_j,a_j))^2 (and change model Q)\n",
    "    end for\n",
    "end for\n",
    "```\n",
    "\n",
    "## OpenAI functions\n",
    "\n",
    "- env = gym.make(environment_name) <- sets up the environment\n",
    "- env.reset() <- resets the environment to starting point\n",
    "- env.step(action) <- takes action and goes to state $S_{t+1}$, returns $r_t$, $S_{t+1}$ and if game terminated.\n",
    "- env.render() <- render the output\n",
    "\n",
    "\n",
    "## Reference:\n",
    "\n",
    "- https://keon.io/deep-q-learning/\n",
    "- http://mckinziebrandon.me/TensorflowNotebooks/2016/12/21/openai.html\n",
    "- https://github.com/yenchenlin/DeepLearningFlappyBird\n",
    "- [Playing Atari with Deep Reinforcement Learning](https://www.cs.toronto.edu/~vmnih/docs/dqn.pdf)\n",
    "- [OpenAI environments](https://gym.openai.com/envs/)\n",
    "- https://www.youtube.com/watch?v=JFJkpVWTQVM\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/Z93Kdli6G4k?rel=0&amp;controls=0&amp;showinfo=0\" frameborder=\"0\" allowfullscreen></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import HTML\n",
    "HTML('<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/Z93Kdli6G4k?rel=0&amp;controls=0&amp;showinfo=0\" frameborder=\"0\" allowfullscreen></iframe>')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/t3m4cciKfe8?rel=0&amp;controls=0&amp;showinfo=0\" frameborder=\"0\" allowfullscreen></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "HTML('<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/t3m4cciKfe8?rel=0&amp;controls=0&amp;showinfo=0\" frameborder=\"0\" allowfullscreen></iframe>')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: gym in /Users/sachin/anaconda/lib/python3.5/site-packages\n",
      "Requirement already satisfied: six in /Users/sachin/anaconda/lib/python3.5/site-packages (from gym)\n",
      "Requirement already satisfied: numpy>=1.10.4 in /Users/sachin/anaconda/lib/python3.5/site-packages (from gym)\n",
      "Requirement already satisfied: pyglet>=1.2.0 in /Users/sachin/anaconda/lib/python3.5/site-packages (from gym)\n",
      "Requirement already satisfied: requests>=2.0 in /Users/sachin/anaconda/lib/python3.5/site-packages (from gym)\n",
      "Requirement already satisfied: idna<2.7,>=2.5 in /Users/sachin/anaconda/lib/python3.5/site-packages (from requests>=2.0->gym)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /Users/sachin/anaconda/lib/python3.5/site-packages (from requests>=2.0->gym)\n",
      "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /Users/sachin/anaconda/lib/python3.5/site-packages (from requests>=2.0->gym)\n",
      "Requirement already satisfied: urllib3<1.23,>=1.21.1 in /Users/sachin/anaconda/lib/python3.5/site-packages (from requests>=2.0->gym)\n",
      "Fetching package metadata .............\n",
      "Solving package specifications: .\n",
      "\n",
      "# All requested packages already installed.\n",
      "# packages in environment at /Users/sachin/anaconda:\n",
      "#\n",
      "jsanimation               0.1                      py35_0    conda-forge\n"
     ]
    }
   ],
   "source": [
    "!pip install gym\n",
    "!conda install -y JSAnimation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import re\n",
    "\n",
    "from keras.models import Sequential, Model\n",
    "from keras.layers import Dense, Input, Dot\n",
    "from keras.models import load_model, model_from_json\n",
    "from keras.optimizers import Adam\n",
    "\n",
    "import gym\n",
    "\n",
    "from collections import deque\n",
    "\n",
    "import time\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "# Imports specifically so we can render outputs in Jupyter.\n",
    "from JSAnimation.IPython_display import display_animation\n",
    "from matplotlib import animation\n",
    "from IPython.display import display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def create_model(n_states, n_actions):\n",
    "    # Maximum future discounted reward\n",
    "    # Q(S_t)\n",
    "    state = Input(shape=(n_states,))\n",
    "    x1 = Dense(4, activation='relu')(state)\n",
    "    x2 = Dense(4, activation='relu')(x1)\n",
    "    out = Dense(n_actions)(x2)\n",
    "    # Q(S_t)(a_t)\n",
    "    actions = Input(shape=(n_actions,))\n",
    "    out2 = Dot(axes=-1)([out, actions])\n",
    "    \n",
    "    # wrap the above in Keras Model class\n",
    "    model = Model(inputs=[state, actions], outputs=out2)\n",
    "    model.compile(loss='mse', optimizer='rmsprop')\n",
    "    \n",
    "    model2 = Model(inputs=state, outputs=out)\n",
    "\n",
    "    return model, model2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def train_data(minibatch, model):\n",
    "    s_j_batch = np.array([d[0] for d in minibatch])\n",
    "    a_batch = np.array([d[1] for d in minibatch])\n",
    "    r_batch = np.array([d[2] for d in minibatch])\n",
    "    s_j1_batch = np.array([d[3] for d in minibatch])\n",
    "    terminal_batch = np.array([d[4] for d in minibatch])\n",
    "\n",
    "    readout_j1_batch = model.predict(s_j1_batch, batch_size=BATCH)\n",
    "    y_batch = r_batch + GAMMA * np.max(readout_j1_batch, axis=1)\n",
    "    y_batch[terminal_batch] = r_batch[terminal_batch]\n",
    "    return s_j_batch, a_batch, y_batch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[2017-10-29 15:57:44,293] Making new env: CartPole-v0\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Episode : 0 , time taken:  0.04322099685668945 s, average up time:  1.0\n",
      "Episode : 5000 , time taken:  1.8772480487823486 s, average up time:  97.0784313725\n",
      "Episode : 10000 , time taken:  14.008546113967896 s, average up time:  36.98\n",
      "Episode : 15000 , time taken:  13.076855897903442 s, average up time:  70.53\n",
      "Episode : 20000 , time taken:  12.869633913040161 s, average up time:  104.74\n",
      "Episode : 25000 , time taken:  12.837337017059326 s, average up time:  133.49\n",
      "Episode : 30000 , time taken:  12.839324951171875 s, average up time:  146.25\n",
      "Episode : 35000 , time taken:  13.132809162139893 s, average up time:  144.52\n",
      "Episode : 40000 , time taken:  12.963682889938354 s, average up time:  167.73\n",
      "Episode : 45000 , time taken:  13.547950029373169 s, average up time:  181.39\n",
      "Episode : 50000 , time taken:  14.607528924942017 s, average up time:  170.48\n",
      "Episode : 55000 , time taken:  15.984797954559326 s, average up time:  151.86\n",
      "Episode : 60000 , time taken:  16.933092832565308 s, average up time:  146.43\n",
      "Episode : 65000 , time taken:  17.319180965423584 s, average up time:  163.32\n",
      "Episode : 70000 , time taken:  17.957252979278564 s, average up time:  184.96\n",
      "Episode : 75000 , time taken:  21.94894814491272 s, average up time:  198.13\n",
      "Episode : 80000 , time taken:  24.839221000671387 s, average up time:  171.12\n",
      "Episode : 85000 , time taken:  24.760560035705566 s, average up time:  136.11\n",
      "Episode : 90000 , time taken:  20.755791902542114 s, average up time:  116.67\n",
      "Episode : 95000 , time taken:  21.71216917037964 s, average up time:  97.53\n"
     ]
    }
   ],
   "source": [
    "env = gym.make('CartPole-v0')\n",
    "STATES, ACTIONS = env.observation_space.shape[0], env.action_space.n\n",
    "model, out = create_model(STATES, ACTIONS)\n",
    "INITIAL_EPSILON = 1e-1\n",
    "FINAL_EPSILON = 1e-4\n",
    "DECAY = 0.9\n",
    "GAMMA = 0.9 # decay rate of past observations\n",
    "OBSERVE = 5000. # timesteps to observe before training\n",
    "REPLAY_MEMORY = 5000 # number of previous transitions to remember\n",
    "TIME_LIMIT = 100000\n",
    "BATCH = 128\n",
    "# open up a game state to communicate with emulator\n",
    "state = env.reset()\n",
    "\n",
    "# store the previous observations in replay memory\n",
    "D = deque(maxlen=REPLAY_MEMORY)\n",
    "loss = []\n",
    "\n",
    "a_t = np.zeros(ACTIONS)\n",
    "a_t[np.random.choice(ACTIONS)] = 1\n",
    "s_t, r_0, terminal, _ = env.step(np.argmax(a_t))\n",
    "\n",
    "# start training\n",
    "epsilon = INITIAL_EPSILON\n",
    "\n",
    "up_time = [0]\n",
    "start = time.time()\n",
    "for t in range(TIME_LIMIT):\n",
    "    # choose an action\n",
    "    readout_t = out.predict(s_t[None, :])\n",
    "    a_t = np.zeros([ACTIONS])\n",
    "    if np.random.random() <= epsilon:\n",
    "        a_t[np.random.choice(ACTIONS)] = 1\n",
    "    else:\n",
    "        a_t[np.argmax(readout_t)] = 1\n",
    "\n",
    "    # scale down epsilon\n",
    "    if epsilon > FINAL_EPSILON and t > OBSERVE:\n",
    "        epsilon *= DECAY\n",
    "\n",
    "    # run the selected action and observe next state and reward\n",
    "    # store the transition in D\n",
    "    s_t1, r_t, terminal, _ = env.step(np.argmax(a_t))\n",
    "    D.append((s_t, a_t, r_t, s_t1, terminal))\n",
    "    \n",
    "    if terminal:\n",
    "        up_time.append(0)\n",
    "        env.reset()\n",
    "    else:\n",
    "        up_time[-1] += r_t\n",
    "    \n",
    "    # only train if done observing\n",
    "    if t > OBSERVE:\n",
    "        # sample a minibatch to train on\n",
    "        idx = np.random.choice(REPLAY_MEMORY, BATCH, replace=False)\n",
    "        minibatch = [D[i] for i in idx]\n",
    "        # get the batch variables\n",
    "        s_t_batch, a_batch, y_batch = train_data(minibatch, out)\n",
    "        # perform gradient step\n",
    "        loss.append(model.train_on_batch([s_t_batch, a_batch], y_batch))\n",
    "\n",
    "    # update the old state\n",
    "    s_t = s_t1\n",
    "        \n",
    "    if t%(TIME_LIMIT/20)==0:\n",
    "        print('Episode :', t, ', time taken: ', time.time() - start, 's, average up time: ',np.mean(up_time[-100:]))\n",
    "        start = time.time()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nA+no4UPcKPLQAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1202ab7f0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(12, 5))\n",
    "plt.plot(up_time)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nvkpnAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1202ab5f8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(12, 5))\n",
    "plt.plot(loss)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Only run the following if you are running it locally and not in Docker**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def display_frames_as_gif(frames):\n",
    "    \"\"\"\n",
    "    Displays a list of frames as a gif, with controls\n",
    "    \"\"\"\n",
    "    #plt.figure(figsize=(frames[0].shape[1] / 72.0, frames[0].shape[0] / 72.0), dpi = 72)\n",
    "    patch = plt.imshow(frames[0])\n",
    "    plt.axis('off')\n",
    "\n",
    "    def animate(i):\n",
    "        patch.set_data(frames[i])\n",
    "\n",
    "    anim = animation.FuncAnimation(plt.gcf(), animate, frames = len(frames), interval=50)\n",
    "    display(display_animation(anim, default_mode='once'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[2017-10-29 16:04:01,470] Making new env: CartPole-v0\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Define the Animation class */\n",
       "  function Animation(frames, img_id, slider_id, interval, loop_select_id){\n",
       "    this.img_id = img_id;\n",
       "    this.slider_id = slider_id;\n",
       "    this.loop_select_id = loop_select_id;\n",
       "    this.interval = interval;\n",
       "    this.current_frame = 0;\n",
       "    this.direction = 0;\n",
       "    this.timer = null;\n",
       "    this.frames = new Array(frames.length);\n",
       "\n",
       "    for (var i=0; i<frames.length; i++)\n",
       "    {\n",
       "     this.frames[i] = new Image();\n",
       "     this.frames[i].src = frames[i];\n",
       "    }\n",
       "    document.getElementById(this.slider_id).max = this.frames.length - 1;\n",
       "    this.set_frame(this.current_frame);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.get_loop_state = function(){\n",
       "    var button_group = document[this.loop_select_id].state;\n",
       "    for (var i = 0; i < button_group.length; i++) {\n",
       "        var button = button_group[i];\n",
       "        if (button.checked) {\n",
       "            return button.value;\n",
       "        }\n",
       "    }\n",
       "    return undefined;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.set_frame = function(frame){\n",
       "    this.current_frame = frame;\n",
       "    document.getElementById(this.img_id).src = this.frames[this.current_frame].src;\n",
       "    document.getElementById(this.slider_id).value = this.current_frame;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.next_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.previous_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.max(0, this.current_frame - 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.first_frame = function()\n",
       "  {\n",
       "    this.set_frame(0);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.last_frame = function()\n",
       "  {\n",
       "    this.set_frame(this.frames.length - 1);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.slower = function()\n",
       "  {\n",
       "    this.interval /= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.faster = function()\n",
       "  {\n",
       "    this.interval *= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_forward = function()\n",
       "  {\n",
       "    this.current_frame += 1;\n",
       "    if(this.current_frame < this.frames.length){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.first_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.last_frame();\n",
       "        this.reverse_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.last_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_reverse = function()\n",
       "  {\n",
       "    this.current_frame -= 1;\n",
       "    if(this.current_frame >= 0){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.last_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.first_frame();\n",
       "        this.play_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.first_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.pause_animation = function()\n",
       "  {\n",
       "    this.direction = 0;\n",
       "    if (this.timer){\n",
       "      clearInterval(this.timer);\n",
       "      this.timer = null;\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.play_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = 1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.reverse_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = -1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n",
       "  }\n",
       "</script>\n",
       "\n",
       "<div class=\"animation\" align=\"center\">\n",
       "    <img id=\"_anim_imgUYKANTEOQDEJFLEV\">\n",
       "    <br>\n",
       "    <input id=\"_anim_sliderUYKANTEOQDEJFLEV\" type=\"range\" style=\"width:350px\" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\" onchange=\"animUYKANTEOQDEJFLEV.set_frame(parseInt(this.value));\"></input>\n",
       "    <br>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.slower()\">&#8211;</button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.first_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.previous_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.reverse_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.pause_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.play_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.next_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.last_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animUYKANTEOQDEJFLEV.faster()\">+</button>\n",
       "  <form action=\"#n\" name=\"_anim_loop_selectUYKANTEOQDEJFLEV\" class=\"anim_control\">\n",
       "    <input type=\"radio\" name=\"state\" value=\"once\" checked> Once </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"loop\" > Loop </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"reflect\" > Reflect </input>\n",
       "  </form>\n",
       "</div>\n",
       "\n",
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Instantiate the Animation class. */\n",
       "  /* The IDs given should match those used in the template above. */\n",
       "  (function() {\n",
       "    var img_id = \"_anim_imgUYKANTEOQDEJFLEV\";\n",
       "    var slider_id = \"_anim_sliderUYKANTEOQDEJFLEV\";\n",
       "    var loop_select_id = \"_anim_loop_selectUYKANTEOQDEJFLEV\";\n",
       "    var frames = new Array(0);\n",
       "    \n",
       "  frames[0] = \"\"\n",
       "  frames[1] = \"\"\n",
       "  frames[2] = \"\"\n",
       "  frames[3] = \"\"\n",
       "  frames[4] = \"\"\n",
       "  frames[5] = \"\"\n",
       "  frames[6] = \"\"\n",
       "  frames[7] = \"\"\n",
       "  frames[8] = \"\"\n",
       "  frames[9] = \"\"\n",
       "  frames[10] = \"\"\n",
       "  frames[11] = \"\"\n",
       "  frames[12] = \"\"\n",
       "  frames[13] = \"\"\n",
       "  frames[14] = \"\"\n",
       "  frames[15] = \"\"\n",
       "\n",
       "\n",
       "    /* set a timeout to make sure all the above elements are created before\n",
       "       the object is initialized. */\n",
       "    setTimeout(function() {\n",
       "        animUYKANTEOQDEJFLEV = new Animation(frames, img_id, slider_id, 50, loop_select_id);\n",
       "    }, 0);\n",
       "  })()\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n"
     ]
    }
   ],
   "source": [
    "env = gym.make('CartPole-v0')\n",
    "\n",
    "# Run a demo of the environment\n",
    "observation = env.reset()\n",
    "cum_reward = 0\n",
    "frames = []\n",
    "for t in range(5000):\n",
    "    # Render into buffer. \n",
    "    frames.append(env.render(mode = 'rgb_array'))\n",
    "    action = env.action_space.sample()\n",
    "    observation, reward, done, info = env.step(action)\n",
    "    if done:\n",
    "        break\n",
    "env.render(close=True)\n",
    "display_frames_as_gif(frames)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Define the Animation class */\n",
       "  function Animation(frames, img_id, slider_id, interval, loop_select_id){\n",
       "    this.img_id = img_id;\n",
       "    this.slider_id = slider_id;\n",
       "    this.loop_select_id = loop_select_id;\n",
       "    this.interval = interval;\n",
       "    this.current_frame = 0;\n",
       "    this.direction = 0;\n",
       "    this.timer = null;\n",
       "    this.frames = new Array(frames.length);\n",
       "\n",
       "    for (var i=0; i<frames.length; i++)\n",
       "    {\n",
       "     this.frames[i] = new Image();\n",
       "     this.frames[i].src = frames[i];\n",
       "    }\n",
       "    document.getElementById(this.slider_id).max = this.frames.length - 1;\n",
       "    this.set_frame(this.current_frame);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.get_loop_state = function(){\n",
       "    var button_group = document[this.loop_select_id].state;\n",
       "    for (var i = 0; i < button_group.length; i++) {\n",
       "        var button = button_group[i];\n",
       "        if (button.checked) {\n",
       "            return button.value;\n",
       "        }\n",
       "    }\n",
       "    return undefined;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.set_frame = function(frame){\n",
       "    this.current_frame = frame;\n",
       "    document.getElementById(this.img_id).src = this.frames[this.current_frame].src;\n",
       "    document.getElementById(this.slider_id).value = this.current_frame;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.next_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.previous_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.max(0, this.current_frame - 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.first_frame = function()\n",
       "  {\n",
       "    this.set_frame(0);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.last_frame = function()\n",
       "  {\n",
       "    this.set_frame(this.frames.length - 1);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.slower = function()\n",
       "  {\n",
       "    this.interval /= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.faster = function()\n",
       "  {\n",
       "    this.interval *= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_forward = function()\n",
       "  {\n",
       "    this.current_frame += 1;\n",
       "    if(this.current_frame < this.frames.length){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.first_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.last_frame();\n",
       "        this.reverse_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.last_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_reverse = function()\n",
       "  {\n",
       "    this.current_frame -= 1;\n",
       "    if(this.current_frame >= 0){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.last_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.first_frame();\n",
       "        this.play_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.first_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.pause_animation = function()\n",
       "  {\n",
       "    this.direction = 0;\n",
       "    if (this.timer){\n",
       "      clearInterval(this.timer);\n",
       "      this.timer = null;\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.play_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = 1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.reverse_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = -1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n",
       "  }\n",
       "</script>\n",
       "\n",
       "<div class=\"animation\" align=\"center\">\n",
       "    <img id=\"_anim_imgHQTEPCSOBUZKDJTL\">\n",
       "    <br>\n",
       "    <input id=\"_anim_sliderHQTEPCSOBUZKDJTL\" type=\"range\" style=\"width:350px\" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\" onchange=\"animHQTEPCSOBUZKDJTL.set_frame(parseInt(this.value));\"></input>\n",
       "    <br>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.slower()\">&#8211;</button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.first_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.previous_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.reverse_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.pause_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.play_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.next_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.last_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHQTEPCSOBUZKDJTL.faster()\">+</button>\n",
       "  <form action=\"#n\" name=\"_anim_loop_selectHQTEPCSOBUZKDJTL\" class=\"anim_control\">\n",
       "    <input type=\"radio\" name=\"state\" value=\"once\" checked> Once </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"loop\" > Loop </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"reflect\" > Reflect </input>\n",
       "  </form>\n",
       "</div>\n",
       "\n",
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Instantiate the Animation class. */\n",
       "  /* The IDs given should match those used in the template above. */\n",
       "  (function() {\n",
       "    var img_id = \"_anim_imgHQTEPCSOBUZKDJTL\";\n",
       "    var slider_id = \"_anim_sliderHQTEPCSOBUZKDJTL\";\n",
       "    var loop_select_id = \"_anim_loop_selectHQTEPCSOBUZKDJTL\";\n",
       "    var frames = new Array(0);\n",
       "    \n",
       "  frames[0] = \"\"\n",
       "  frames[1] = \"\"\n",
       "  frames[2] = \"\"\n",
       "  frames[3] = \"\"\n",
       "  frames[4] = \"\"\n",
       "  frames[5] = \"\"\n",
       "  frames[6] = \"\"\n",
       "  frames[7] = \"\"\n",
       "  frames[8] = \"\"\n",
       "  frames[9] = \"\"\n",
       "  frames[10] = \"\"\n",
       "  frames[11] = \"\"\n",
       "  frames[12] = \"\"\n",
       "  frames[13] = \"\"\n",
       "  frames[14] = \"\"\n",
       "  frames[15] = \"\"\n",
       "  frames[16] = \"\"\n",
       "  frames[17] = \"\"\n",
       "  frames[18] = \"\"\n",
       "  frames[19] = \"\"\n",
       "  frames[20] = \"\"\n",
       "  frames[21] = \"\"\n",
       "  frames[22] = \"\"\n",
       "  frames[23] = \"\"\n",
       "  frames[24] = \"\"\n",
       "  frames[25] = \"\"\n",
       "  frames[26] = \"\"\n",
       "  frames[27] = \"\"\n",
       "  frames[28] = \"\"\n",
       "  frames[29] = \"\"\n",
       "  frames[30] = \"\"\n",
       "  frames[31] = \"\"\n",
       "  frames[32] = \"\"\n",
       "  frames[33] = \"\"\n",
       "  frames[34] = \"\"\n",
       "  frames[35] = \"\"\n",
       "  frames[36] = \"\"\n",
       "  frames[37] = \"\"\n",
       "  frames[38] = \"\"\n",
       "  frames[39] = \"\"\n",
       "  frames[40] = \"\"\n",
       "  frames[41] = \"\"\n",
       "  frames[42] = \"\"\n",
       "  frames[43] = \"\"\n",
       "  frames[44] = \"\"\n",
       "  frames[45] = \"\"\n",
       "  frames[46] = \"\"\n",
       "  frames[47] = \"\"\n",
       "  frames[48] = \"\"\n",
       "  frames[49] = \"\"\n",
       "  frames[50] = \"\"\n",
       "  frames[51] = \"\"\n",
       "  frames[52] = \"\"\n",
       "  frames[53] = \"\"\n",
       "  frames[54] = \"\"\n",
       "  frames[55] = \"\"\n",
       "  frames[56] = \"\"\n",
       "  frames[57] = \"\"\n",
       "  frames[58] = \"\"\n",
       "  frames[59] = \"\"\n",
       "  frames[60] = \"\"\n",
       "  frames[61] = \"\"\n",
       "  frames[62] = \"\"\n",
       "  frames[63] = \"\"\n",
       "  frames[64] = \"\"\n",
       "  frames[65] = \"\"\n",
       "  frames[66] = \"\"\n",
       "  frames[67] = \"\"\n",
       "  frames[68] = \"\"\n",
       "  frames[69] = \"\"\n",
       "  frames[70] = \"\"\n",
       "  frames[71] = \"\"\n",
       "  frames[72] = \"\"\n",
       "  frames[73] = \"\"\n",
       "  frames[74] = \"\"\n",
       "  frames[75] = \"\"\n",
       "  frames[76] = \"\"\n",
       "  frames[77] = \"\"\n",
       "  frames[78] = \"\"\n",
       "  frames[79] = \"\"\n",
       "  frames[80] = \"\"\n",
       "  frames[81] = \"\"\n",
       "  frames[82] = \"\"\n",
       "  frames[83] = \"\"\n",
       "  frames[84] = \"\"\n",
       "  frames[85] = \"\"\n",
       "  frames[86] = \"\"\n",
       "  frames[87] = \"\"\n",
       "  frames[88] = \"\"\n",
       "  frames[89] = \"\"\n",
       "  frames[90] = \"\"\n",
       "  frames[91] = \"\"\n",
       "  frames[92] = \"\"\n",
       "  frames[93] = \"\"\n",
       "  frames[94] = \"\"\n",
       "  frames[95] = \"\"\n",
       "  frames[96] = \"\"\n",
       "  frames[97] = \"\"\n",
       "  frames[98] = \"\"\n",
       "  frames[99] = \"\"\n",
       "  frames[100] = \"\"\n",
       "  frames[101] = \"\"\n",
       "  frames[102] = \"\"\n",
       "  frames[103] = \"\"\n",
       "  frames[104] = \"\"\n",
       "  frames[105] = \"\"\n",
       "  frames[106] = \"\"\n",
       "  frames[107] = \"\"\n",
       "  frames[108] = \"\"\n",
       "  frames[109] = \"\"\n",
       "  frames[110] = \"\"\n",
       "  frames[111] = \"\"\n",
       "  frames[112] = \"\"\n",
       "  frames[113] = \"\"\n",
       "  frames[114] = \"\"\n",
       "\n",
       "\n",
       "    /* set a timeout to make sure all the above elements are created before\n",
       "       the object is initialized. */\n",
       "    setTimeout(function() {\n",
       "        animHQTEPCSOBUZKDJTL = new Animation(frames, img_id, slider_id, 50, loop_select_id);\n",
       "    }, 0);\n",
       "  })()\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "114\n"
     ]
    }
   ],
   "source": [
    "# Run a demo of the environment\n",
    "observation = env.reset()\n",
    "cum_reward = 0\n",
    "frames = []\n",
    "a_t = np.zeros([ACTIONS])\n",
    "a_t[env.action_space.sample()] = 1\n",
    "for t in range(5000):\n",
    "    # Render into buffer.  \n",
    "    s_t, reward, done, info = env.step(np.argmax(a_t))\n",
    "    frames.append(env.render(mode = 'rgb_array'))\n",
    "    readout_t = out.predict(s_t[None, :])\n",
    "    a_t = np.zeros([ACTIONS])\n",
    "    a_t[np.argmax(readout_t)] = 1\n",
    "    \n",
    "    if done:\n",
    "        break\n",
    "env.render(close=True)\n",
    "display_frames_as_gif(frames)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "width = height = 32\n",
    "n_channels = 3\n",
    "n_features = 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.models import Model\n",
    "from keras.layers import Conv2D, MaxPool2D, Dense, Input, Concatenate, Flatten\n",
    "\n",
    "image = Input(shape=(width, height, n_channels))\n",
    "x1 = Conv2D(8, kernel_size=(5, 5), activation='relu', padding='same')(image)\n",
    "x1 = MaxPool2D(pool_size=(2,2))(x1)\n",
    "\n",
    "x2 = Conv2D(16, kernel_size=(5, 5), activation='relu', padding='same')(x1)\n",
    "x2 = MaxPool2D(pool_size=(2,2))(x2)\n",
    "\n",
    "x3 = Conv2D(32, kernel_size=(5, 5), activation='relu', padding='same')(x2)\n",
    "x3 = MaxPool2D(pool_size=(2,2))(x3)\n",
    "\n",
    "x3 = Flatten()(x3)\n",
    "\n",
    "other_info = Input(shape=(n_features,))\n",
    "x1_other = Dense(10, activation='relu')(other_info)\n",
    "\n",
    "x4 = Concatenate()([x3, x1_other])\n",
    "\n",
    "x5 = Dense(1, activation='sigmoid')(x4)\n",
    "\n",
    "model = Model(inputs=[image, other_info], outputs=x5)\n",
    "model.compile(loss='binary_crossentropy', optimizer='adam')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "____________________________________________________________________________________________________\n",
      "Layer (type)                     Output Shape          Param #     Connected to                     \n",
      "====================================================================================================\n",
      "input_2 (InputLayer)             (None, 32, 32, 3)     0                                            \n",
      "____________________________________________________________________________________________________\n",
      "conv2d_4 (Conv2D)                (None, 32, 32, 8)     608                                          \n",
      "____________________________________________________________________________________________________\n",
      "max_pooling2d_4 (MaxPooling2D)   (None, 16, 16, 8)     0                                            \n",
      "____________________________________________________________________________________________________\n",
      "conv2d_5 (Conv2D)                (None, 16, 16, 16)    3216                                         \n",
      "____________________________________________________________________________________________________\n",
      "max_pooling2d_5 (MaxPooling2D)   (None, 8, 8, 16)      0                                            \n",
      "____________________________________________________________________________________________________\n",
      "conv2d_6 (Conv2D)                (None, 8, 8, 32)      12832                                        \n",
      "____________________________________________________________________________________________________\n",
      "max_pooling2d_6 (MaxPooling2D)   (None, 4, 4, 32)      0                                            \n",
      "____________________________________________________________________________________________________\n",
      "input_3 (InputLayer)             (None, 3)             0                                            \n",
      "____________________________________________________________________________________________________\n",
      "flatten_2 (Flatten)              (None, 512)           0                                            \n",
      "____________________________________________________________________________________________________\n",
      "dense_1 (Dense)                  (None, 10)            40                                           \n",
      "____________________________________________________________________________________________________\n",
      "concatenate_1 (Concatenate)      (None, 522)           0                                            \n",
      "____________________________________________________________________________________________________\n",
      "dense_2 (Dense)                  (None, 1)             523                                          \n",
      "====================================================================================================\n",
      "Total params: 17,219.0\n",
      "Trainable params: 17,219.0\n",
      "Non-trainable params: 0.0\n",
      "____________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"702pt\" viewBox=\"0.00 0.00 367.50 702.00\" width=\"368pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 698)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-698 363.5,-698 363.5,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- 4825646472 -->\n",
       "<g class=\"node\" id=\"node1\"><title>4825646472</title>\n",
       "<polygon fill=\"none\" points=\"41.5,-657.5 41.5,-693.5 170.5,-693.5 170.5,-657.5 41.5,-657.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-671.8\">input_2: InputLayer</text>\n",
       "</g>\n",
       "<!-- 4825646416 -->\n",
       "<g class=\"node\" id=\"node2\"><title>4825646416</title>\n",
       "<polygon fill=\"none\" points=\"42.5,-584.5 42.5,-620.5 169.5,-620.5 169.5,-584.5 42.5,-584.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-598.8\">conv2d_4: Conv2D</text>\n",
       "</g>\n",
       "<!-- 4825646472&#45;&gt;4825646416 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>4825646472-&gt;4825646416</title>\n",
       "<path d=\"M106,-657.313C106,-649.289 106,-639.547 106,-630.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"109.5,-630.529 106,-620.529 102.5,-630.529 109.5,-630.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825623912 -->\n",
       "<g class=\"node\" id=\"node3\"><title>4825623912</title>\n",
       "<polygon fill=\"none\" points=\"0,-511.5 0,-547.5 212,-547.5 212,-511.5 0,-511.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-525.8\">max_pooling2d_4: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 4825646416&#45;&gt;4825623912 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>4825646416-&gt;4825623912</title>\n",
       "<path d=\"M106,-584.313C106,-576.289 106,-566.547 106,-557.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"109.5,-557.529 106,-547.529 102.5,-557.529 109.5,-557.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825623352 -->\n",
       "<g class=\"node\" id=\"node4\"><title>4825623352</title>\n",
       "<polygon fill=\"none\" points=\"42.5,-438.5 42.5,-474.5 169.5,-474.5 169.5,-438.5 42.5,-438.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-452.8\">conv2d_5: Conv2D</text>\n",
       "</g>\n",
       "<!-- 4825623912&#45;&gt;4825623352 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>4825623912-&gt;4825623352</title>\n",
       "<path d=\"M106,-511.313C106,-503.289 106,-493.547 106,-484.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"109.5,-484.529 106,-474.529 102.5,-484.529 109.5,-484.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825654272 -->\n",
       "<g class=\"node\" id=\"node5\"><title>4825654272</title>\n",
       "<polygon fill=\"none\" points=\"0,-365.5 0,-401.5 212,-401.5 212,-365.5 0,-365.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-379.8\">max_pooling2d_5: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 4825623352&#45;&gt;4825654272 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>4825623352-&gt;4825654272</title>\n",
       "<path d=\"M106,-438.313C106,-430.289 106,-420.547 106,-411.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"109.5,-411.529 106,-401.529 102.5,-411.529 109.5,-411.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825646920 -->\n",
       "<g class=\"node\" id=\"node6\"><title>4825646920</title>\n",
       "<polygon fill=\"none\" points=\"42.5,-292.5 42.5,-328.5 169.5,-328.5 169.5,-292.5 42.5,-292.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-306.8\">conv2d_6: Conv2D</text>\n",
       "</g>\n",
       "<!-- 4825654272&#45;&gt;4825646920 -->\n",
       "<g class=\"edge\" id=\"edge5\"><title>4825654272-&gt;4825646920</title>\n",
       "<path d=\"M106,-365.313C106,-357.289 106,-347.547 106,-338.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"109.5,-338.529 106,-328.529 102.5,-338.529 109.5,-338.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825743488 -->\n",
       "<g class=\"node\" id=\"node7\"><title>4825743488</title>\n",
       "<polygon fill=\"none\" points=\"0,-219.5 0,-255.5 212,-255.5 212,-219.5 0,-219.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-233.8\">max_pooling2d_6: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 4825646920&#45;&gt;4825743488 -->\n",
       "<g class=\"edge\" id=\"edge6\"><title>4825646920-&gt;4825743488</title>\n",
       "<path d=\"M106,-292.313C106,-284.289 106,-274.547 106,-265.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"109.5,-265.529 106,-255.529 102.5,-265.529 109.5,-265.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825787696 -->\n",
       "<g class=\"node\" id=\"node9\"><title>4825787696</title>\n",
       "<polygon fill=\"none\" points=\"65,-146.5 65,-182.5 177,-182.5 177,-146.5 65,-146.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"121\" y=\"-160.8\">flatten_2: Flatten</text>\n",
       "</g>\n",
       "<!-- 4825743488&#45;&gt;4825787696 -->\n",
       "<g class=\"edge\" id=\"edge7\"><title>4825743488-&gt;4825787696</title>\n",
       "<path d=\"M109.631,-219.313C111.326,-211.289 113.384,-201.547 115.281,-192.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"118.76,-193.036 117.402,-182.529 111.911,-191.589 118.76,-193.036\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825881456 -->\n",
       "<g class=\"node\" id=\"node8\"><title>4825881456</title>\n",
       "<polygon fill=\"none\" points=\"230.5,-219.5 230.5,-255.5 359.5,-255.5 359.5,-219.5 230.5,-219.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"295\" y=\"-233.8\">input_3: InputLayer</text>\n",
       "</g>\n",
       "<!-- 4825882072 -->\n",
       "<g class=\"node\" id=\"node10\"><title>4825882072</title>\n",
       "<polygon fill=\"none\" points=\"226.5,-146.5 226.5,-182.5 331.5,-182.5 331.5,-146.5 226.5,-146.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"279\" y=\"-160.8\">dense_1: Dense</text>\n",
       "</g>\n",
       "<!-- 4825881456&#45;&gt;4825882072 -->\n",
       "<g class=\"edge\" id=\"edge8\"><title>4825881456-&gt;4825882072</title>\n",
       "<path d=\"M291.127,-219.313C289.319,-211.289 287.123,-201.547 285.1,-192.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"288.45,-191.515 282.837,-182.529 281.622,-193.054 288.45,-191.515\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825972408 -->\n",
       "<g class=\"node\" id=\"node11\"><title>4825972408</title>\n",
       "<polygon fill=\"none\" points=\"113.5,-73.5 113.5,-109.5 286.5,-109.5 286.5,-73.5 113.5,-73.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"200\" y=\"-87.8\">concatenate_1: Concatenate</text>\n",
       "</g>\n",
       "<!-- 4825787696&#45;&gt;4825972408 -->\n",
       "<g class=\"edge\" id=\"edge9\"><title>4825787696-&gt;4825972408</title>\n",
       "<path d=\"M140.124,-146.313C150.119,-137.33 162.51,-126.193 173.423,-116.386\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"175.954,-118.816 181.052,-109.529 171.275,-113.61 175.954,-118.816\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4825882072&#45;&gt;4825972408 -->\n",
       "<g class=\"edge\" id=\"edge10\"><title>4825882072-&gt;4825972408</title>\n",
       "<path d=\"M259.876,-146.313C249.881,-137.33 237.49,-126.193 226.577,-116.386\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"228.725,-113.61 218.948,-109.529 224.046,-118.816 228.725,-113.61\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 4826105392 -->\n",
       "<g class=\"node\" id=\"node12\"><title>4826105392</title>\n",
       "<polygon fill=\"none\" points=\"147.5,-0.5 147.5,-36.5 252.5,-36.5 252.5,-0.5 147.5,-0.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"200\" y=\"-14.8\">dense_2: Dense</text>\n",
       "</g>\n",
       "<!-- 4825972408&#45;&gt;4826105392 -->\n",
       "<g class=\"edge\" id=\"edge11\"><title>4825972408-&gt;4826105392</title>\n",
       "<path d=\"M200,-73.3129C200,-65.2895 200,-55.5475 200,-46.5691\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"203.5,-46.5288 200,-36.5288 196.5,-46.5289 203.5,-46.5288\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "\n",
    "SVG(model_to_dot(model).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "____________________________________________________________________________________________________\n",
      "Layer (type)                     Output Shape          Param #     Connected to                     \n",
      "====================================================================================================\n",
      "input_2 (InputLayer)             (None, 32, 32, 3)     0                                            \n",
      "____________________________________________________________________________________________________\n",
      "conv2d_4 (Conv2D)                (None, 32, 32, 8)     608                                          \n",
      "____________________________________________________________________________________________________\n",
      "max_pooling2d_4 (MaxPooling2D)   (None, 16, 16, 8)     0                                            \n",
      "____________________________________________________________________________________________________\n",
      "conv2d_5 (Conv2D)                (None, 16, 16, 16)    3216                                         \n",
      "____________________________________________________________________________________________________\n",
      "max_pooling2d_5 (MaxPooling2D)   (None, 8, 8, 16)      0                                            \n",
      "____________________________________________________________________________________________________\n",
      "conv2d_6 (Conv2D)                (None, 8, 8, 32)      12832                                        \n",
      "____________________________________________________________________________________________________\n",
      "max_pooling2d_6 (MaxPooling2D)   (None, 4, 4, 32)      0                                            \n",
      "____________________________________________________________________________________________________\n",
      "input_3 (InputLayer)             (None, 3)             0                                            \n",
      "____________________________________________________________________________________________________\n",
      "flatten_2 (Flatten)              (None, 512)           0                                            \n",
      "____________________________________________________________________________________________________\n",
      "dense_1 (Dense)                  (None, 10)            40                                           \n",
      "____________________________________________________________________________________________________\n",
      "concatenate_1 (Concatenate)      (None, 522)           0                                            \n",
      "____________________________________________________________________________________________________\n",
      "dense_2 (Dense)                  (None, 1)             523                                          \n",
      "====================================================================================================\n",
      "Total params: 17,219.0\n",
      "Trainable params: 17,219.0\n",
      "Non-trainable params: 0.0\n",
      "____________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "latex_envs": {
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 0
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
